package com.aiatomic.countlib;

import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;

class MsgManager {
    Socket socket;
    InputStream inputStream;
    OutputStream outputStream;
    final String REGISTER = "register";
    final String UN_REGISTER = "un_register";
    final String HB = "hb";
    final String OK = "ok";
    String port;
    boolean unregister = false;
    ArrayBlockingQueue<Msg> queue = new ArrayBlockingQueue<>(10);
    private OnDisconnectSuccessListener l;
    Runnable hbTask = new Runnable() {
        @Override
        public void run() {
            while (!socket.isClosed() && !socket.isOutputShutdown() && !unregister) {
                try {
                    Thread.sleep(60000);
                    Msg msg = new Msg();
                    msg.type = HB;
                    msg.content = "client-hb:" + System.currentTimeMillis();
                    queue.add(msg);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    Runnable writeTask =new Runnable() {
        @Override
        public void run() {
            while (!socket.isClosed() && !socket.isOutputShutdown()&& !unregister) {
                try {
                    Msg msg = queue.take();
                    WriteHelper.sendData(outputStream, msg.type);
                    if (msg.content != null) {
                        WriteHelper.sendData(outputStream, msg.content);
                    }
                } catch (InterruptedException | IOException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    Runnable readTask = new Runnable() {
        @Override
        public void run() {
            while (!socket.isClosed() && !socket.isInputShutdown() && !unregister) {
                String read = ReadHelper.read(inputStream);
                Log.i("MsgManager", read);
                if (read.startsWith("connect_block_ok") && l != null) {
                    l.onDisconnect();
                }
                clear();
            }
        }
    };

    public void clear() {
        queue.clear();
    }

    public interface OnConnectSuccessListener {
        void onConnect(String port);
    }

    public interface OnDisconnectSuccessListener {
        void onDisconnect();
    }

    public MsgManager() throws IOException {
        try {
            socket = new Socket();
            socket.connect(new InetSocketAddress("10.0.3.2", 6666), 500);
        } catch (Exception e) {
            socket = new Socket("10.0.2.2", 6666);
        }
        inputStream = socket.getInputStream();
        outputStream = socket.getOutputStream();
    }

    public void connect(String localIp, OnConnectSuccessListener l) throws IOException {
        WriteHelper.sendData(outputStream, REGISTER);
        WriteHelper.sendData(outputStream, localIp);
        String result = ReadHelper.read(inputStream);
        if (OK.equals(result)) {
            port = ReadHelper.read(inputStream);
            if (l != null) {
                l.onConnect(port);
            }
            startHeartBeatThread();
        }
    }

    public void disconnect(OnDisconnectSuccessListener l) {
        this.l = l;
        unregister = true;
        Msg msg = new Msg();
        msg.type = UN_REGISTER;
        queue.clear();
        queue.add(msg);
    }

    private void startHeartBeatThread() {
        new Thread(hbTask).start();
        new Thread(writeTask).start();
        new Thread(readTask).start();
    }
}
